import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 
 */


public class P2PFileTransfer {
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {

		int port = 7000;		
		FileServer fileServer = new FileServer(port);
		fileServer.transferFile();
	}
}


/**
 * Accepts requests for transfering files.
 * @author LN
 *
 */
class FileServer {
	
	int _port;
	ServerSocket _server;
	//BufferedReader _bufferReaderIn = null;
	DataInputStream _dataIn = null;
		
	public FileServer(int port) {
		_port = port;
		InetAddress addr;
		try {
			addr = InetAddress.getLocalHost();
			System.out.println("IP: " + addr.getHostAddress());
			System.out.println("Port: " + port);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} 		
	}

	
	public void transferFile() {
				
		try {						
			// all addresses on localhost
			_server = new ServerSocket(_port, 5, null );
			
			while (true) {
				System.out.println("Ready to transfer file.");
				Socket sock = _server.accept();
				String filename="";
				try {
					System.out.println("Waiting for  file request...");
					_dataIn = new DataInputStream(sock.getInputStream());		// deprecated readLine()
								
					while (_dataIn.available() <= 0) {
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							System.out.println(e);
						}													
					}
					/* receive response from server */
								
					filename = _dataIn.readUTF();
					System.out.println("File to send: \"" + filename + "\"");														
															
					File file = new File(filename);
					FileInputStream fileInStream = new FileInputStream(file);
					OutputStream socketOutStream = sock.getOutputStream();
					byte [] bytearray  = new byte [(int)file.length()];
																		
				    int chunkSize;
				    while ( (chunkSize = fileInStream.read(bytearray)) != -1 ) {
				    	// Send file to client
					    System.out.println("Sending file...");
				    	socketOutStream.write(bytearray, 0, chunkSize);				    	
				    }				    				   
				    socketOutStream.flush();			// VERY IMPORTANT
				    System.out.println("\"" + filename + "\" has been sent.");
				    
				    socketOutStream.close();
				    fileInStream.close();
				    sock.close();
				}
				catch (IOException ex) {
					System.out.println("getInput/OutputStream() failed.");
				    System.exit(-1);
				}
			}
		}
		catch (IOException ex) {			
			System.out.println(ex.toString());
			System.out.println("Could not listen on port " + _port);
		    System.exit(-1);
		}			
	}
	
	/*
	 * Called before exit. Cleans up ServerSocket objects.
	 * (non-Javadoc)
	 * @see java.lang.Object#finalize()
	 */
	protected void finalize() {
		/* Clean up*/

	}
}
